home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ADA Programming Guide
/
ADA Programming Guide.iso
/
ada_gwu
/
adahelp.c
< prev
next >
Wrap
Text File
|
1996-01-30
|
30KB
|
1,071 lines
/*
HELP ENGINE PARA GWADA
Módulo ADAHELP.C
Programa para mostrar helps referentes à linguagem ADA.
O arquivo de help GWADA.HLP deve ser gerado através do
programa ADAHCONV.EXE.
Trabalho de conclusao
Bacharelado em Informática
Ulrich Peters
Rafael Presotto
Jerry Dressler
Revisoes:
/03 Início do trabalho
/04 Reformulaçao completa do sistema de acesso ao help, definiçao do
ambiente da Help-Engine (janela/sombra/botoes...)
/05 Introduçao das funçoes de mouse
/06 Barra de rolagem e ativaçao desta pelo mouse, testes dos desvios
/08 Testes com alocaçao estática/dinâmica de memória - erro
provável no tamanho do registro de linha de help
15/08 Verificaçao do sistema gráfico acoplado - atributos de sublinhado
e highlight para monitores MDA/Hercules e cores para sist. coloridos
09/09 Revisao das funçoes do mouse para o caso de driver nao estar instalado
13/09 Volta para a mesma posiçao (scroll) anterior ao ativar ALT-F1,
modificaçao das mensagens de erro, início das procuras por strings
passados como parâmetro de chamada
16/09 Correçao no vetor de chamadas de help (31 posiçoes em vez de 30!)
/10 Excecuçao da procura de tokens, montar tokenbuffer (help virtual) para
o string passado como parâmetro, desvio direto para help se houver
apenas um desvio localizado.
/11 Revisao completa nas estruturas de alocacao dinâmica e testes finais
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
#include <dos.h>
#include <ctype.h>
#include "..\source\gwadahlp.h"
#include "..\source\adavio.h"
#include "..\source\mouse.h"
#define destaca_desvio(pointer) (VioColor(pointer->screen_Xi,pointer->screen_Y+scroll, pointer->screen_Xf,pointer->screen_Y+scroll, attrib.select))
#define desmarca_desvio(pointer) (VioColor(pointer->screen_Xi,pointer->screen_Y+scroll, pointer->screen_Xf,pointer->screen_Y+scroll, attrib.desvio))
/* Estrutura usada para guardar uma linha de texto de auxílio */
typedef struct helpline
{
struct helpline *prox;
char helptext[77];
};
/* Estrutura única para guardar os vários atributos de cor usados */
typedef struct cores
{
char normal; /* texto normal do help */
char hilight; /* texto destacado */
char desvio; /* texto de desvio */
char dimmed; /* texto escuro (inativo) */
char select; /* texto selecionado */
char slider0; /* barra de rolagem */
char slider1; /* cursor da barra de rolagem */
};
/* listas globais */
struct desvio *desvio_mostrado;
struct helpline *hlptxt;
struct cores attrib;
int chamadas[31]; /* vetor das chamadas efetuadas p/ backtracking */
int cham_scr[31]; /* vetor da posiçao do help na tela */
int chmds; /* número de chamadas de helps anteriores */
/* outras variáveis globais */
FILE *help; /* arquivo GWADA.HLP */
int mouse=0; /* controle: driver instalado? */
int ha_desvio;
int sliderpos; /* posiçao do slider */
int ALT_F1, TAB, ENTER; /* variáveis para controlar os buttons */
int scroll_pos; /* posiçao do help na tela */
char far *tokenbuffer; /* buffer que simula help de tokens achados */
int tokenlines; /* linhas achadas por search() */
/* Funçoes de controle do mouse */
void mouse_on(void)
{
if (mouse)
mouse_enable();
}
void mouse_off(void)
{
if (mouse)
mouse_disable();
}
/* Rotina para terminar com erro */
void end(char *texto, int exitcode)
{
int posicao;
char pre[70];
if (texto != "")
{
if (exitcode != 2)
strcpy(pre,"Memory Fault: ");
else
strcpy(pre,"");
strcat(pre,texto);
posicao = 40-strlen(pre)/2;
VioSombra(posicao-1,9,45+(40-posicao),13);
VioFill(posicao-3,8,43+(40-posicao),12,' ',0x4F);
VioFrame(posicao-3,8,43+(40-posicao),12,0,0x4F);
VioPrint(posicao,10,0x4F,0,pre);
while (! kbhit());
}
while (kbhit())
posicao = getch(); /* Limpar buffer do teclado */
VioWinClose(1); /* Fechar janela e restaura tela */
_setcursortype(_NORMALCURSOR); /* retornar cursor */
exit(exitcode);
}
/* Sinal acústico para erro */
void beep(void)
{
sound(500);
delay(10);
nosound();
}
/* Buscar lista de helps disponíveis do disco
(Informaçoes do cabeçalho do arquivo) */
void ler_nodos(void)
{
int qtde; /* número de nodos */
int i;
struct tree *nodo_antes;
raiz = NULL;
fread(&qtde,2,1,help); /* recuperar número de nodos do arquivo */
nodo_antes = NULL;
nodo_atual = malloc(sizeof(struct tree));
for (i=0;i<qtde;i++) /* recuperar os nodos no início do help */
{
fread(&nodo_atual->number,2,1,help);
fread(&nodo_atual->lines,2,1,help);
fread(&nodo_atual->size,4,1,help);
fread(&nodo_atual->offset,4,1,help);
nodo_atual-> prox = NULL;
if (raiz == NULL) raiz = nodo_atual;
nodo_antes = nodo_atual;
nodo_atual = malloc(sizeof(struct tree));
nodo_antes->prox = nodo_atual;
}
nodo_antes->prox = NULL;
free(nodo_atual); /* eliminar a última criaçao de nodo */
}
/* Extrair do buffer de memória o texto do help,
montando a lista encadeada dos desvios e
a lista de texto de help (scrolling) */
void process_buffer(char far *buffer, int linhas)
{
int pos, n, x, i;
char numero[5];
struct helpline *texto, *linha_anterior;
/* Inicializa ponteiros da listas */
hlptxt = NULL; /* raiz dos helps */
draiz = NULL; /* raiz dos desvios */
braiz = NULL; /* raiz dos brancos */
linha_anterior = NULL;
desvio_antes = NULL;
branco_antes = NULL;
i=0;
for (x=0;x<linhas;x++)
{
/* alocar memória para a texto */
texto = (struct helpline *)farmalloc(sizeof(struct helpline));
if (texto == NULL)
end("HELPLINE",1);
pos = 0;
while (buffer[i] != '\n')
{
if (buffer[i] == '\\') /* início de sequência de controle */
{
switch (buffer[++i])
{
case 'u' : /* alocar nodo na árvore de brancos */
i++;
branco_atual = (struct branco *)farmalloc(sizeof(struct branco));
if (branco_atual == NULL)
end("HILIGHTED TEXT LIST",1);
branco_atual->screen_Xi = pos+2;
branco_atual->screen_Y = x+2; /* 2 = margem da moldura! */
while ((buffer[i] != '\\')&&(pos < 76))
texto->helptext[pos++] = buffer[i++];
branco_atual->screen_Xf = pos+1;
i += 2;
branco_atual->prox = NULL;
if (braiz == NULL)
braiz = branco_atual;
if (branco_antes != NULL)
branco_antes->prox = branco_atual;
branco_antes = branco_atual;
break;
case 'v' : /* alocar nodo da arvore de desvios */
i++;
desvio_atual = (struct desvio *)farmalloc(sizeof(struct desvio));
if (desvio_atual == NULL)
end("TRANSFER LIST",1);
desvio_atual->screen_Xi = pos+2;
desvio_atual->screen_Y = x+2; /* 2 = margem da moldura! */
while ((buffer[i] != '\\')&&(pos < 76))
texto->helptext[pos++] = buffer[i++];
desvio_atual->screen_Xf = pos+1;
i += 2; /* pular o '\v' */
/* extrair o número do desvio */
n=0;
while (buffer[i] != '.')
numero[n++] = buffer[i++];
i++; /* pular o '.' */
numero[n] = '\0';
desvio_atual->number = atoi(numero);
if (numero == 0) /* linha invalida: apaga destaque */
free(desvio_atual);
else
{
desvio_atual->prox = NULL;
if (draiz == NULL)
draiz = desvio_atual;
if (desvio_antes != NULL)
desvio_antes->prox = desvio_atual;
desvio_antes = desvio_atual;
}
break;
}
}
if (pos < 76)
texto->helptext[pos++] = buffer[i];
i++;
}
/* encontrou um caractere \n */
i++;
if (pos)
texto->helptext[pos-1] = '\0';
else
texto->helptext[pos] = '\0';
texto->prox = NULL;
if (hlptxt == NULL)
hlptxt = texto;
if (linha_anterior != NULL)
linha_anterior->prox = texto;
linha_anterior = texto;
}
}
/* Funçoes de controle da régua de botoes */
void tab(int ativar)
{
mouse_off();
if (ativar)
{
TAB = 1;
VioColor(36,21,41,21,attrib.desvio); /* TAB ativo */
}
else
{
TAB = 0;
VioColor(36,21,41,21,attrib.dimmed); /* TAB inativo */
}
mouse_on();
}
void enter(int ativar)
{
mouse_off();
if (ativar)
{
ENTER = 1;
VioColor(52,21,57,21,attrib.desvio); /* ENTER ativo */
}
else
{
ENTER = 0;
VioColor(52,21,57,21,attrib.dimmed); /* ENTER inativo */
}
mouse_on();
}
void alt_f1(int ativar)
{
mouse_off();
if (ativar)
{
ALT_F1 = 1;
VioColor(17,21,23,21,attrib.desvio);
}
else
{
ALT_F1 = 0;
VioColor(17,21,23,21,attrib.dimmed); /* ALT-F1 inativo */
}
mouse_on();
}
/* Verifica posiçao do mouse na régua de botoes */
int testa_limites(int ref, int lim_inf, int lim_sup, int bool)
{
if ((ref >= lim_inf) && (ref <= lim_sup) && (bool))
{
mouse_off();
VioWinOpen(lim_inf,21,lim_sup,21);
VioColor(lim_inf,21,lim_sup,21,attrib.select); /* destaca botao */
mouse_on();
while ((mouse) && (buttons)) /* mantém enquanto botao pressionado */
mouse_read();
mouse_off();
VioWinClose(1); /* copia janela de volta - apaga destaque */
mouse_on();
return(1);
}
else
return(0);
}
/* Destacar desvios do texto do help na tela */
void mostra_desvios(int scroll)
{
ha_desvio=0;
tab(0);
desvio_atual = draiz;
while (desvio_atual != NULL) /* até final da lista... */
{
if ((desvio_atual->screen_Y + scroll > 1)&&(desvio_atual->screen_Y + scroll < 20))
{
VioColor(desvio_atual->screen_Xi,desvio_atual->screen_Y+scroll, \
desvio_atual->screen_Xf,desvio_atual->screen_Y+scroll, attrib.desvio);
ha_desvio = 1;
}
desvio_atual = desvio_atual->prox;
if (ha_desvio)
tab(1);
}
}
void mostra_brancos(int scroll)
{
branco_atual = braiz;
while (branco_atual != NULL) /* até final da lista... */
{
if ((branco_atual->screen_Y + scroll > 1) && \
(branco_atual->screen_Y + scroll < 20))
VioColor(branco_atual->screen_Xi,branco_atual->screen_Y+scroll, \
branco_atual->screen_Xf,branco_atual->screen_Y+scroll, attrib.hilight);
branco_atual = branco_atual->prox;
}
}
/* Mostra a barra de rolagem e desenha o slider
na posiçao correspondente a do texto atual */
int mostra_barra_rolagem(int tamanho, int posicao)
{
int slider, i;
posicao *= -1;
for (i=3;i<19;i++) /* desenha barra */
VioPrint(78,i,attrib.slider0,0,"▒");
tamanho -= 18;
if (tamanho > 0) /* calcula posiçao */
{
slider = 15*(float)((float)tamanho-(float)posicao)/((float)tamanho);
slider -= 12;
VioPrintf(78,slider,attrib.slider1,0,"%c",254);
return(slider);
}
else
return(0);
}
/* Mostrar uma janela do help atual, sendo
"scroll" o número de linhas pelo qual o texto
já foi movido para cima na tela (negativo) */
int rolagem(int scroll,int linhas)
{
struct helpline *linha_atual;
int i, y;
mouse_off();
/* limpa janela de texto */
VioFill(2,2,77,19,' ',attrib.normal);
linha_atual = hlptxt;
y = -1 * scroll;
/* pular linhas fora da tela */
for (i=0;i<y;i++)
linha_atual = linha_atual->prox;
/* mostrar linhas válidas */
for (i=0;((i<18)&&(linha_atual != NULL));i++)
{
VioPrint(2,i+2,attrib.normal,0,linha_atual->helptext);
linha_atual = linha_atual->prox;
}
mostra_desvios(scroll);
mostra_brancos(scroll);
/* se havia desvio destacado na tela, mostrar este
desvio na posiçao atual (depois da rolagem) */
if (desvio_mostrado != NULL)
{
if ((desvio_mostrado->screen_Y + scroll > 1)&&(desvio_mostrado->screen_Y + scroll < 20))
{
destaca_desvio(desvio_mostrado);
enter(1);
}
else
{
desvio_mostrado = NULL;
enter(0);
}
}
sliderpos = mostra_barra_rolagem(linhas,y);
mouse_on();
return(i);
}
/* Procura por uma certa palavra no índice */
int search(char *texto)
{
char initial;
char linha_U[150], linha[150];
char titulo[150], tu, ti;
int x, lin, help_num, pos, index, occur, offset=0;
size_t memory;
char far *buffer_temp;
int trunc = 0;
VioPrint(28,11,attrib.hilight,0,"Searching... please wait");
initial = toupper(texto[0]);
/* Determina o número do help correspondente a inicial da palavra
procurada (token) */
switch (initial)
{
case 'A': help_num = 20; break;
case 'B': help_num = 21; break;
case 'C': help_num = 22; break;
case 'D': help_num = 23; break;
case 'E': help_num = 24; break;
case 'F': help_num = 25; break;
case 'G': help_num = 26; break;
case 'H': help_num = 27; break;
case 'I':
case 'J': help_num = 28; break;
case 'K':
case 'L': help_num = 29; break;
case 'M': help_num = 30; break;
case 'N': help_num = 31; break;
case 'O': help_num = 32; break;
case 'P': help_num = 33; break;
case 'Q': help_num = 34; break;
case 'R': help_num = 35; break;
case 'S': help_num = 36; break;
case 'T': help_num = 37; break;
case 'U': help_num = 38; break;
case 'V': help_num = 39; break;
case 'W': help_num = 40; break;
default : help_num = 41; /* X, Y e Z */
}
/* busca o help de índice correspondente... */
nodo_atual = raiz;
while ((nodo_atual->number != help_num)&&(nodo_atual != NULL))
nodo_atual = nodo_atual->prox;
memory = nodo_atual->size;
/* aloca memória para buffer temporário e ler help */
buffer_temp = (char *)farmalloc(memory+2);
if (buffer_temp == NULL)
end("BUFFER TEMP",1);
fseek(help,nodo_atual->offset,0);
fread(buffer_temp,memory,1, help);
buffer_temp[memory] = '\0';
/* montar argumento de procura - texto em maiúsculas */
for (x=0; x<strlen(texto); x++)
texto[x] = toupper(texto[x]);
/* começar a procura... */
strcpy(tokenbuffer,"\\uGWAda Help Engine Token Search\\n\r\n\n");
occur = 0;
while ((occur == 0)&&(strlen(texto) > 0))
{
pos = 0;
lin = 0;
while (lin < nodo_atual->lines) /* enquanto nao fim do help... */
{
index = 0;
while ((buffer_temp[pos] != '\n')&&(index < 80))
linha[index++] = buffer_temp[pos++];
linha[--index] = '\0'; /* final de linha */
lin++;
pos++;
/* linha de texto extraída - agora testar argumentos! */
if (linha[0] != ' ')
{
strcpy(titulo,linha); /* salva como título, já que nao começa com espaço */
tu = 0; /* controle: título usado = 0 */
ti = 0; /* controle: título inserido = 0 */
}
strcpy(linha_U,linha);
for (x=0; x<strlen(linha_U); x++)
linha_U[x] = toupper(linha_U[x]); /* transforma toda linha em maiúsculas */
if (strstr(linha_U,texto) != NULL)
{
if (linha[0] != ' ') /* é um título */
tu = 1;
else
{
if ((tu == 0)&&(ti == 0)) /* título ainda nao usado! */
{
ti = 1; /* título inserido = 1: em título si nao satisfaz token, */
/* mas um item sim, logo inserir título antes do item! */
offset = strlen(tokenbuffer);
if (offset < 8000)
{
strcat(tokenbuffer,titulo); /* inserir título antes da linha recuada */
offset = strlen(tokenbuffer);
tokenbuffer[offset++] = '\r';
tokenbuffer[offset++] = '\n';
tokenbuffer[offset++] = '\0';
occur++;
}
}
}
offset = strlen(tokenbuffer);
if (offset < 8000)
{
strcat(tokenbuffer,linha);
offset = strlen(tokenbuffer);
tokenbuffer[offset++] = '\r';
tokenbuffer[offset++] = '\n';
tokenbuffer[offset++] = '\0';
occur++;
}
else
trunc = 1;
VioPrintf(33,13,attrib.slider0,0," %d bytes ",offset);
}
else
{
/* nao satisfez a condiçao de procura, mas... */
if ((tu == 1)&&(linha[0] == ' '))
{
/* linha é um subitem de um TITULO que satisfaz a condiçao de procura! */
/* logo também deverá ser copiada */
offset = strlen(tokenbuffer);
if (offset < 8000)
{
strcat(tokenbuffer,linha);
offset = strlen(tokenbuffer);
tokenbuffer[offset++] = '\r';
tokenbuffer[offset++] = '\n';
tokenbuffer[offset++] = '\0';
occur++;
}
else
trunc = 1;
}
}
}
if (occur == 0) /* nao achou este token, logo */
texto[strlen(texto)-1] = '\0'; /* tentar cortar a última letra */
} /* para tentar de novo */
if (trunc)
{
beep();
strcat(tokenbuffer,"\r\n< Search truncated >\r\n");
}
else
{
if (!occur)
strcat(tokenbuffer,"\r\n< No matches found - press \\uF1\\n >\r\n");
else
strcat(tokenbuffer,"\r\n< End >\r\n");
}
farfree(buffer_temp);
tokenlines = occur+4;
return(tokenlines);
}
/* Funçao que mostra help,
retornando eventualmente um número
de outro help a ser mostrado */
int showhelp(int number, int scroll, char *token)
{
size_t memory;
char far *buffer;
struct helpline *linha;
int abandonar = 0;
int retorna = 0;
unsigned char tecla;
int lines;
scroll_pos = scroll; /* posiçao anterior deste texto */
/* número < 0 --> mostrar o TOKENBUFFER
número > 0 --> buscar dados de arquivo */
if (number > 0) /* ARQUIVO!!! */
{
/* Varrer a lista encadeada pelo número do help solicitado */
nodo_atual = raiz;
while ((nodo_atual->number != number)&&(nodo_atual != NULL))
nodo_atual = nodo_atual->prox;
/* Help nao existe, logo nao pode chamar outro - retornar 0 */
if (nodo_atual == NULL)
return(0);
/* Help localizado, alocar memória para texto */
memory = nodo_atual->size;
buffer = (char *)farmalloc(memory+2);
if (buffer == NULL)
end("BUFFER",1);
/* Extrair o help do arquivo */
fseek(help,nodo_atual->offset,0);
fread(buffer,memory,1, help);
buffer[memory] = '\0';
lines = nodo_atual->lines;
process_buffer(buffer,lines);
farfree(buffer);
}
else
{
if (strcmp(token,"")) /* TOKENBUFFER!!! */
tokenlines = search(token);
lines = tokenlines;
process_buffer(tokenbuffer,tokenlines);
if ((draiz != NULL)&&(draiz->prox == NULL)) /* há apenas um único desvio: */
return(draiz->number); /* desvia diretamente!! */
}
/* Os dois métodos convergem aqui:
Mostrar help na tela */
rolagem(scroll,lines);
/* zerar ponteiros de controle... */
desvio_mostrado = NULL;
desvio_antes = NULL;
/* Help está na tela agora, esperar pelo usuário */
if (mouse) /* há mouse instalado? */
{
mouse_enable(); /* sim, habilita */
mouse_read();
}
while (! abandonar)
{
if (mouse) /* testar mouse, se houver */
mouse_read();
mouse_x /= 8;
mouse_y /= 8;
if (buttons) /* botao do mouse pressionado! E agora? */
{
if (desvio_mostrado != NULL) /* salvar este desvio... */
desvio_antes = desvio_mostrado;
/* testar posiçao do mouse por desvio válido... */
desvio_atual = draiz;
while ((desvio_atual != NULL) \
&& !((desvio_atual->screen_Y + scroll == mouse_y) \
&& (desvio_atual->screen_Xi <= mouse_x)&&(desvio_atual->screen_Xf >= mouse_x) \
&& (mouse_y < 20)))
desvio_atual = desvio_atual->prox;
if (desvio_atual != NULL)
/* foi selecionado um novo desvio atraves do mouse ? */
{
if (desvio_mostrado != NULL)
/* já teve desvio marcado antes - desmarcar anterior */
desmarca_desvio(desvio_mostrado);
/* marcar desvio atual */
mouse_off();
destaca_desvio(desvio_atual);
mouse_on();
retorna = desvio_atual->number;
abandonar = 1;
scroll_pos = scroll;
while ((mouse) && (buttons)) mouse_read();
}
/* mouse na área de rolagem? */
if ((mouse_x == 78)&&(mouse_y < 19)&&(mouse_y > 2))
{
if (mouse_y < sliderpos)
ungetch(200); /* seta para cima */
if (mouse_y > sliderpos)
ungetch(208); /* seta para baixo */
}
/* mouse na área dos botoes? */
if (mouse_y == 21)
{
tecla = buttons; /* SIMULAR TECLADO!! */
if (testa_limites(mouse_x,2,11,1)) ungetch(187); /* F1 */
if (testa_limites(mouse_x,17,31,ALT_F1)) ungetch(232); /* Alt-F1 */
if ((buttons == 1) && testa_limites(mouse_x,36,47,TAB))
tecla = ungetch(9); /* tecla esquerda = TAB */
if ((buttons == 2) && testa_limites(mouse_x,36,47,TAB))
tecla = ungetch(143); /* tecla direita = BACKTAB */
if (testa_limites(mouse_x,52,65,ENTER)) ungetch(13); /* ENTER */
if (testa_limites(mouse_x,70,76,1)) ungetch(27); /* ESC */
}
}
if (kbhit()) /* nao interessa se foi teclado ou simulaçao... */
{
tecla = getch();
if (tecla == 0)
tecla = getch() + 128;
switch (tecla)
{
case 9: /* TAB - destacar o próximo desvio */
if (ha_desvio)
{
if (desvio_mostrado == NULL) /* sem campo destacado... */
{
desvio_atual = draiz;
while ((desvio_mostrado == NULL)&&(desvio_atual != NULL))
{
if ((desvio_atual->screen_Y + scroll > 1)&&(desvio_atual->screen_Y + scroll < 20))
{
destaca_desvio(desvio_atual);
desvio_mostrado = desvio_atual;
enter(1);
}
else
desvio_atual = desvio_atual->prox;
}
}
else /* já há um campo destacado */
{
desmarca_desvio(desvio_mostrado);
desvio_mostrado = desvio_mostrado->prox;
if ((desvio_mostrado != NULL)&&(desvio_mostrado->screen_Y + scroll > 1)&&(desvio_mostrado->screen_Y + scroll < 20))
{
destaca_desvio(desvio_mostrado);
enter(1);
}
else
{
desvio_mostrado = NULL; /* força o começo no início da lista */
ungetch(9); /* simula outra entrada... */
}
}
}
else
beep(); /* Nao há nada para destacar... */
break;
case 13: /* ENTER - selecionar desvio destacado */
if (desvio_mostrado == NULL)
beep();
else
{
abandonar = 1;
retorna = desvio_mostrado->number;
scroll_pos = scroll;
}
break;
case 27: /* ESC - fim */
abandonar = 1;
break;
case 143: /* BACKTAB - destacar desvio anterior */
if (TAB) /* há desvios na tela atual? */
{
if (desvio_mostrado == NULL)
{
/* destacar o último desvio da tela atual */
desvio_atual = draiz;
while ((desvio_atual != NULL) && (desvio_atual->prox->screen_Y + scroll < 20) && (desvio_atual->prox != NULL))
desvio_atual = desvio_atual->prox;
destaca_desvio(desvio_atual);
enter(1);
desvio_mostrado = desvio_atual;
}
else
{
/* já havia desvio ativo - destacar o anterior... */
desvio_atual = draiz;
if (desvio_atual == desvio_mostrado)
{
/* a raíz estava ativa - desmarcar */
desmarca_desvio(desvio_atual);
desvio_mostrado = NULL;
ungetch(143); /* simula BACKTAB */
}
else
{
/* algum desvio diferente da raíz ativo... */
while (desvio_atual->prox != desvio_mostrado)
desvio_atual = desvio_atual->prox;
/* testar se o desvio é válido para a tela atual... */
if (desvio_atual->screen_Y + scroll > 1)
{
destaca_desvio(desvio_atual);
desvio_mostrado = desvio_atual;
desvio_atual = desvio_atual->prox;
desmarca_desvio(desvio_atual);
enter(1);
}
else
{
/* desvio anterior nao é válido - simular BACKTAB */
desmarca_desvio(desvio_mostrado);
desvio_mostrado = NULL;
ungetch(143);
}
}
}
}
else
beep();
break;
case 187: /* F1 - mostra help #1 */
abandonar = 1;
retorna = 1;
scroll_pos = scroll;
break;
case 199: /* home - vai até o início do texto */
if (scroll)
{
scroll = 0;
rolagem(scroll,lines);
}
else
beep();
break;
case 200: /* seta para cima */
if (scroll < 0)
rolagem(++scroll,lines);
else
beep();
break;
case 201: /* PgUp */
if (scroll < 0)
{
if (scroll < -18)
scroll += 18; /* sobe uma página */
else
scroll = 0; /* vai até o início */
rolagem(scroll,lines);
}
else
beep();
break;
case 207: /* end - vai até o final do texto */
if (lines > 18 + -1 * scroll)
{
scroll = 18 - lines;
rolagem(scroll,lines);
}
else
beep();
break;
case 208: /* seta para baixo */
if (lines > 18 + -1 * scroll)
rolagem(--scroll,lines);
else
beep();
break;
case 209: /* PgDn */
if (lines > 18 + -1 * scroll)
{
if (lines > 36 + -1 * scroll)
scroll -= 18; /* desce uma página */
else
scroll = 18 - lines; /* vai até o final */
rolagem(scroll,lines);
}
else
beep();
break;
case 232: /* ALT-F1 */
if (chmds > 0)
{
abandonar = 1;
retorna = chamadas[--chmds];
scroll_pos = cham_scr[chmds];
}
else
beep();
if (chmds == 0)
alt_f1(0);
break;
} /* termina switch */
} /* termina if kbhit() */
} /* abandonar! */
/* Liberar memória alocada para as listas... */
linha = hlptxt;
while (linha != NULL)
{
hlptxt = linha;
linha = linha->prox;
farfree(hlptxt);
}
desvio_atual = draiz;
while (desvio_atual != NULL)
{
draiz = desvio_atual;
desvio_atual = desvio_atual->prox;
farfree(draiz);
}
branco_atual = braiz;
while (branco_atual != NULL)
{
braiz = branco_atual;
branco_atual = branco_atual->prox;
farfree(braiz);
}
/* volta ao chamador, informando o número do help escolhido
nos desvios deste texto */
desvio_mostrado = NULL;
mouse_off();
return(retorna);
}
void main(int argc, char *argv[])
{
int i, number, primeira_vez = 1;
char path[30];
/* INICIALIZA MODULO DE ENTRADA DE VIDEO */
VioInit();
if (color)
{
attrib.normal = 0x17; /* fundo azul com letra branca */
attrib.hilight = 0x1F; /* fundo azul com letra em branco intenso */
attrib.desvio = 0x1E; /* fundo azul com letra em amarelo */
attrib.dimmed = 0x18; /* fundo azul com letra cinza */
attrib.select = 0x3E; /* fundo ciano com letra amarela */
attrib.slider0 = 0x13; /* fundo ciano com letra azul */
attrib.slider1 = 0x31; /* fundo azul com letra ciano */
}
else
{
attrib.normal = 0x07; /* fundo preto com letra normal */
attrib.hilight = 0x01; /* fundo preto com letra sublinhada */
attrib.desvio = 0x0F; /* fundo preto com letra em branco intenso */
attrib.dimmed = 0x00; /* fundo preto com letra preta */
attrib.select = 0x70; /* fundo branco com letra preta */
attrib.slider0 = 0x07; /* fundo preto com letra branca */
attrib.slider1 = 0x70; /* fundo branco com letra preta */
}
/* MONTA AMBIENTE DA HELP ENGINE */
VioWinOpen(0,1,79,23);
VioSombra(2,2,79,23);
VioFill(0,1,78,22,' ',attrib.normal);
if (color)
{
VioFrame(0,1,78,22,0,attrib.hilight);
VioPrint(1,20,attrib.hilight,0,VioStrep('─',77));
}
else
{
VioFrame(0,1,78,22,0,attrib.desvio);
VioPrint(1,20,attrib.desvio,0,VioStrep('─',77));
}
VioPrintf(78,2,attrib.slider0,0,"%c",24);
VioPrintf(78,19,attrib.slider0,0,"%c",25);
VioPrintf(2,21,attrib.normal,0,"F1 Summary ALT-F1 Previous %cTAB%c Select ENTER Go Topic ESC End",27,26);
VioColor(2,21,4,21,attrib.desvio); /* F1 ativo */
alt_f1(0); /* ALT-F1 inativo */
tab(0); /* TAB inativo */
enter(0); /* ENTER inativo */
VioColor(70,21,73,21,attrib.desvio); /* ESC ativo */
/* INICIALIZAÇAO */
/* há mouse instalado? */
_setcursortype(_NOCURSOR);
chmds = 0;
if (mouse_reset() == -1) mouse = 1;
strcpy(path,argv[0]);
i = strlen(path);
while(path[i] != '\\') path[i--] = '\0';
strcat(path,"GWADA.HLP");
if ( (help = fopen(path,"rb")) == NULL)
end("Sorry, file GWADA.HLP was not found.",2);
fread(&path,sizeof(header),1,help);
path[sizeof(header)-1] = '\0'; /* Pular a marca de final de arquivo
(0x1A) e terminar o string com \0 */
if (strcmp(path,header) != 0)
end("Sorry, help file seems to be corrupt.",2);
/* Arquivo de help achado, montar agora lista encadeada
através das informaçoes no cabeçalho do arquivo... */
ler_nodos();
/* LOOP DA CONSULTA */
number = 1;
chamadas[chmds] = number; /* índice 0 */
cham_scr[chmds] = 0; /* scroll */
if (argc > 1)
{
tokenbuffer = (char *)farmalloc(8192);
if (tokenbuffer == NULL)
end("TOKEN BUFFER",1);
}
while (number)
{
enter(0); /* ENTER desativado, pois sem campo ativo */
if (chmds)
alt_f1(1); /* ALT-F1 ativo, pois há para onde voltar */
if ((argc > 1)&&(primeira_vez))
{
number = -1;
number = showhelp(number,scroll_pos,argv[1]);
primeira_vez = 0;
if (argc > 1) chamadas[chmds] = -1; // buffer de tokens montado
}
else
number = showhelp(number,scroll_pos,"");
if ((number != chamadas[chmds]) || (scroll_pos != cham_scr[chmds]))
/* inclui apenas se help e/ou posicao diferente */
{
if (++chmds > 30)
{
chmds = 30; /* sao mais de trinta consultas... */
for (i=0;i<30;i++) /* tirar primeira posicao da pilha */
{ /* para criar espaco para a atual */
chamadas[i] = chamadas[i+1];
cham_scr[i] = cham_scr[i+1];
}
}
chamadas[chmds] = number;
cham_scr[chmds-1] = scroll_pos;
scroll_pos = 0;
}
}
/* terminar programa normalmente */
if ((heapcheck() != 2) || (farheapcheck() != 2))
end("Error in (far) heap.",1);
else
end("",0);
}